<template>
  <div id="map"></div>
  <div class="zoombtn">
    <el-button type="primary" @click="zoom_out">Zoom out</el-button>
    <el-button type="primary" @click="zoom_in">Zoom in</el-button>
  </div>
</template>

<script setup>
import { backendData } from '@/js/data'
import Tianditu from '@/utils/Tianditu'
import { onMounted } from 'vue'
import { Map, View } from 'ol'
import { Tile as TileLayer, Vector as VectorLayer, Image as ImageLayer } from "ol/layer";
import { XYZ, WMTS, Vector as VectorSource, TileWMS, ImageWMS } from "ol/source";
import Feature from "ol/Feature";
// 1. 按需引入 OpenLayers 核心模块（避免全量引入，减小打包体积）
import OSM from 'ol/source/OSM';
import WKT from 'ol/format/WKT'; // 解析 WKT 格式的核心模块
import Style from 'ol/style/Style';
import Fill from 'ol/style/Fill';
import Stroke from 'ol/style/Stroke';
// import { fromLonLat, getCenter } from 'ol/proj'; // 坐标转换、范围中心计算工具
// import { getExtent } from 'ol/extent'; // 几何范围计算工具
const TDT = new Tianditu()
const vecLyrGrp = TDT.createTileLayerGroup('vec', true)
let map = null
let baseVectorLayer = null // 基础区域图层（渲染原始区域）
let highlightLayer = null // 高亮图层（凸显目标区域）
let targetFeature = null // 后端解析后的 Feature 对象
onMounted(() => {
  // map = new Map({
  //   layers: [vecLyrGrp],
  //   target: 'map',
  //   view: new View({
  //     center: [12953941.4, 4852833.2],
  //     zoom: 5,
  //     projection: 'EPSG:4326'
  //   }),
  // })
  const img_w = "http://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=ad78a187c042afc866c2a0e24a5b3898"
  let imageLayer = new TileLayer({
    source: new XYZ({
      url: img_w,
      crossOrigin: 'anonymous', // 启用跨域请求
      // 新增：强制设置图片跨域
      tileLoadFunction: (tile, url) => {
        const img = tile.getImage();
        img.crossOrigin = 'anonymous'; // 显式设置
        img.src = url;
        img.onerror = () => console.error('路网瓦片加载失败（跨域可能）:', url);
      },
    }),
    isGroup: true,
    maxZoom: 18,
    name: "天地图路网",
    layerName: 'baseMap'
  });

  let view = new View({
    extent: [-180, -90, 180, 90],
    projection: 'EPSG:4326',
    center: [118.3223, 36.4122],
    zoom: 7,
    minZoom: 1,
    maxZoom: 24,
  });
  map = new Map({
    // layers: [imageLayer, noteLayer],
    layers: [imageLayer],
    target: "map",
    view: view,
    controls: [] // 关键：传入空数组表示不添加任何默认控件
  });


  /**
* 1. 解析后端 WKT 为 OpenLayers Feature（坐标系：EPSG:4326 → 3857）
*/
const parseWktToFeature = () => {
  if (backendData.code !== 200 || !backendData.data) {
    console.error('后端数据异常', backendData);
    return;
  }

  // WKT 解析器：指定原始坐标系为 EPSG:4326（经纬度）
  const wktParser = new WKT({ dataProjection: 'EPSG:4326' });
  try {
    // 解析并转换为地图坐标系（EPSG:3857，与全局 map 一致）
    targetFeature = wktParser.readFeature(backendData.data, {
      featureProjection: 'EPSG:3857'
    });
    // 给 Feature 加自定义属性（方便后续识别）
    targetFeature.set('areaName', '目标高亮区域');
  } catch (err) {
    console.error('WKT 解析失败', err);
  }
}
/**
       * 2. 创建自定义图层（基础区域层 + 高亮层）
       */
const createCustomLayers = () => {
  // ---------------- 基础区域图层（非高亮样式） ----------------
  baseVectorLayer = new VectorLayer({
    source: new VectorSource({
      features: targetFeature ? [targetFeature] : []
    }),
    style: new Style({
      fill: new Fill({ color: 'rgba(100, 149, 237, 0.1)' }), // 浅蓝半透明
      stroke: new Stroke({ color: '#666', width: 5.5 })     // 灰色边框
    })
  });

  // ---------------- 高亮图层（视觉突出样式） ----------------
  highlightLayer = new VectorLayer({
    source: new VectorSource(), // 初始空，动态添加
    style: new Style({
      // fill: new Fill({ color: 'rgba(255, 50, 50, 0.4)' }), // 深红半透明
      stroke: new Stroke({ color: '#ff0000', width: 5.5 }) // 红色粗边框
    })
  });
}
      /**
         * 3. 将自定义图层添加到全局 window.map
         * （图层顺序：基础层在底图之上，高亮层在基础层之上）
         */
      const  addLayersToMap=()=> {
         
            // 先加基础层，再加高亮层（确保层级正确）
            map.addLayer(baseVectorLayer);
            map.addLayer(highlightLayer);

            // 【可选】若需精确控制层级（如放在指定底图之上）：
            // const layers = map.getLayers(); // 获取所有图层
            // layers.insertAt(1, this.baseVectorLayer); // 插入到第1位（0是最底层）
            // layers.insertAt(2, this.highlightLayer);  // 插入到第2位
        }
             /**
         * 4. 自动高亮区域 + 让地图居中到该区域
         */
       const  autoHighlight =()=> {
            if (!targetFeature || !map) return;

            // 清空原有高亮，添加当前区域
            highlightLayer.getSource().clear();
            highlightLayer.getSource().addFeature(targetFeature);

            // 地图居中到区域（带动画）
            const areaExtent = targetFeature.getGeometry().getExtent();
            map.getView().fit(areaExtent, {
                padding: [80, 80, 80, 80], // 内边距：避免区域贴地图边缘
                duration: 1000             // 动画时长：1秒
            });
        }
              /**
         * 5. 绑定地图点击事件（点击区域触发高亮）
         */
      const  bindClickEvent=()=> {
            // 先解绑再绑定：避免组件重复挂载导致多次触发
            map.un('click',handleMapClick);
            map.on('click',handleMapClick);
        }
        
        /**
 * 点击事件处理函数（单独提取，方便解绑）
 */
        const handleMapClick=(e)=> {

            // 检测点击位置的 Feature（只识别基础区域图层）
            map.forEachFeatureAtPixel(e.pixel, (feature) => {
                // 高亮点击的区域
                highlightLayer.getSource().clear();
                highlightLayer.getSource().addFeature(feature);

                // 居中到点击区域
                map.getView().fit(feature.getGeometry().getExtent(), {
                    padding: [80, 80, 80, 80],
                    duration: 500
                });

                console.log('点击区域信息：', feature.getProperties());
                return true; // 停止遍历，只处理第一个匹配的区域
            }, {
                // 过滤图层：只检测基础区域层，排除底图和高亮层
                layerFilter: (layer) => layer === baseVectorLayer
            });
        }
parseWktToFeature(); // 1. 解析 WKT 为 Feature
createCustomLayers(); // 2. 创建基础/高亮图层
addLayersToMap();     // 3. 将图层添加到全局 map
autoHighlight(); // 4. 自动高亮区域并居中
bindClickEvent();     // 5. 绑定点击交互

})

const zoom_in = () => {
  const view = map.getView()
  const zoom = view.getZoom()
  view.setZoom(zoom + 1)
}
const zoom_out = () => {
  const view = map.getView()
  const zoom = view.getZoom()
  view.setZoom(zoom - 1)
}




</script>

<style scoped>
#map {
  width: 100%;
  height: 100%;
}

.zoombtn {
  position: absolute;
  top: 10px;
  right: 10px;
}
</style>